<template>
    <div class="img-tools-container light" v-show="visible">
        <div class="top-part">
            <div class="top-part-left">
                <button class="top-left-btn top-btn-hover" :class="{'top-btn-disabled':!cropperStyle.isReset}" @click="handleResetDraw">
                    <span class="top-btn-content" style="padding: 0 4px;">重置</span>
                </button>
                <button class="top-left-btn top-btn-hover" :class="{'top-btn-disabled':currentImg == 0}" title="撤销" @click="handleChangeImg(false)">
                    <span class="top-btn-content">
                        <i class="iconfont icon-shangyibu top-btn-icon"></i>
                    </span>
                </button>
                <button class="top-left-btn top-btn-hover" :class="{ 'top-btn-disabled': currentImg >= imgHistoryList.length - 1 }" title="恢复" @click="handleChangeImg(true)">
                    <span class="top-btn-content">
                        <i class="iconfont icon-xiayibu top-btn-icon"></i>
                    </span>
                </button>
            </div>
            <div class="top-part-center">
                <div class="top-center-content">
                    <button class="top-center-btn" :class="{ 'is-select': item.id == id }" v-for="item in toolList"
                        :key="item.id" @click="selectTool(item)">
                        <i :class="`icon-${item.icon} iconfont top-btn-icon`"></i>
                        <span>{{ item.title }}</span>
                    </button>
                </div>
            </div>
            <div class="top-part-right">
                <button class="top-right-btn">保存</button>
                <button class="top-right-btn cancel-btn">取消</button>
            </div>
        </div>

        <div class="img-part">
            <div style="width: 100%;height: 100%">
                <canvas class="canvas-container" :style="{cursor:cursorStyle}" :width="containerWidth" :height="containerHeight"
                    ref="canvasRef" @mousemove="canvasMouseMove" @mousedown="canvasMouseDown"></canvas>
            </div>
            <div class="img-container"
                :style="{ height: imgHeight + 'px',width: imgWidth + 'px' }">
                <div v-show="id == 1" class="img-cropper" :style="{
                    width: cropperStyle.width + 'px',
                    height: cropperStyle.height + 'px',
                    left: cropperStyle.left + 'px',
                    top: cropperStyle.top + 'px'
                }">
                    <div class="left-first-line img-cropper-line" :style="{ opacity: cropperStyle.cutLineOpacity }">
                    </div>
                    <div class="left-second-line img-cropper-line" :style="{ opacity: cropperStyle.cutLineOpacity }">
                    </div>
                    <div class="top-first-line img-cropper-line" :style="{ opacity: cropperStyle.cutLineOpacity }">
                    </div>
                    <div class="top-second-line img-cropper-line" :style="{ opacity: cropperStyle.cutLineOpacity }">
                    </div>
                    <div class="left-top-border img-cropper-border img-drag"></div>
                    <div class="left-bottom-border img-cropper-border img-drag"></div>
                    <div class="right-top-border img-cropper-border img-drag"></div>
                    <div class="right-bottom-border img-cropper-border img-drag"></div>
                    <div class="top-middle-border img-drag"></div>
                    <div class="left-middle-border img-drag"></div>
                    <div class="right-middle-border img-drag"></div>
                    <div class="bottom-middle-border img-drag"></div>
                </div>
            </div>
        </div>

        <RotationBar ref="rotationBarRef" v-if="id == 1" :width="containerWidth" @finish="finishRotate" @rotate="handleRotate" />

        <!--
        <div class="footer-btn footer-justify-content" v-else>
            <i class="iconfont icon-cha" style="font-size: 20px" title="取消" @click="handleCancel"></i>
            <i class="iconfont icon-gou" style="font-size: 20px" title="确定" @click="handleConfirm"></i>
        </div> -->
    </div>
</template>

<script setup lang="ts">
import { reactive, ref, computed, onMounted } from "vue";
import "@/assets/icon/iconfont.css";
import { ImgToolsType, ImgToolsList, RotationBarType,CanvasConfigType } from "@/components/imgTools/types/type";
import { useImgCopper } from '@/components/imgTools/hooks/copper'
import RotationBar from '@/components/imgTools/component/rotationBar.vue'
import { deepCopy } from "@/utils";
import { useImgMove } from "./hooks/move";

const visible = ref(false)
const rotationBarRef = ref<RotationBarType>();

const canvasRef = ref<HTMLCanvasElement>();
const ctx = computed(() => canvasRef.value?.getContext('2d') as CanvasRenderingContext2D)

// canvas区域大小
const containerWidth = ref(0)
const containerHeight = ref(0)
const initWidth = ref(0) //图片初始宽度

const toolOptions = reactive<ImgToolsType>({
    img: "",
    maxHeight: "auto",
    minCropperSize: 100,
    zoom: 1,
    opacity: 0.8,
    scale: 0.7,
})

// 存储图片版本
const imgHistoryList = ref<CanvasConfigType[]>([])
const currentImg = ref(0)

// 图片的大小
const imgWidth = ref(0)
const imgHeight = ref(0)
/**
 * 初始化
 * @param file 图片文件
 * @param options 配置项
 */
const createImgTools = (file: File, options?: Partial<ImgToolsType>) => {
    visible.value = true
    loadFile(file)
    if (options) {
        Object.assign({}, toolOptions, options)
    }
}

// 将文件转成base64
const loadFile = (file: File) => {
    const reader = new FileReader()
    reader.onloadend = () => {
        initCanvas(reader.result as string)
        setImgOptions({left:0,top:0,width:0,height:0,baseUrl:reader.result as string,degree:0})
    }
    reader.readAsDataURL(file)
}

//canvas初始化
let imgBox = new Image()
const initCanvas = (url: string) => {
    imgBox.src = url
    imgBox.onload = () => {
        resizeObserver()
    }
}

const setCanvasImage = () => {
    // // canvas区域的高度需要根据图片比例进行计算
    // imgHeight.value = imgWidth.value / imgBox.width * imgBox.height
    if(id.value == 1){
        handleCropper(imgHistoryList.value[currentImg.value])
    }
}

// 存储每次变化的canvas参数
const setImgOptions = (config:CanvasConfigType) => {
    if(currentImg.value < imgHistoryList.value.length){
        currentImg.value++
        imgHistoryList.value = imgHistoryList.value.slice(0,currentImg.value)
    }
    imgHistoryList.value.push(config)
}

// 旋转完成
const finishRotate = async (rotateObj:{degree:string,originX:number,originMove:number}) => {
    await confirmCropper()
    const config = deepCopy(imgHistoryList.value[currentImg.value])
    imgHistoryList.value[currentImg.value] = {...config,...rotateObj}
}

// 用来切换模式
const id = ref(1);
// 工具列表
const toolList = reactive<ImgToolsList[]>([
    { id: 1, title: "裁剪", icon: "caijian" },
    { id: 2, title: "压缩", icon: "yasuotupian" },
]);

/**
 * 选择工具函数
 * @param item 工具列表中的工具项
 * @returns 无返回值
 */
const selectTool = (item: ImgToolsList) => {
    id.value = item.id;
};

// 裁剪
const {
    cropperStyle,
    setCutPart,
    handleCropper,
    handleResetCropper,
    confirmCropper,
    handleRotate,
} = useImgCopper(imgWidth, imgHeight, toolOptions, imgBox, canvasRef, ctx, imgHistoryList, currentImg,setImgOptions)

// 拖拽
const {
    canvasMouseMove,
    canvasMouseDown,
    cursorStyle,
} = useImgMove(toolOptions,cropperStyle,containerWidth,containerHeight,imgWidth,imgHeight,setCutPart)

// 响应式
const resizeObserver = () => {
    const imgDom = document.querySelector('.img-part') as Element
    const ob = new ResizeObserver((e) => {
        if (visible) {
            containerWidth.value = e[0].contentRect.width
            containerHeight.value = e[0].contentRect.height
            toolOptions.zoom = imgWidth.value != 0 ? containerWidth.value * toolOptions.scale / initWidth.value : 1
            if(imgBox.width > imgBox.height){
                imgWidth.value = containerWidth.value * toolOptions.scale
                // canvas区域的高度需要根据图片比例进行计算
                imgHeight.value = imgWidth.value / imgBox.width * imgBox.height
            }else{
                imgHeight.value = containerHeight.value * toolOptions.scale
                // canvas区域的宽度需要根据图片比例进行计算
                imgWidth.value = imgHeight.value / imgBox.height * imgBox.width
            }
            if(initWidth.value == 0) initWidth.value = imgWidth.value
            setCanvasImage()
            ob.disconnect()
        }
    })
    ob.observe(imgDom)
}

onMounted(() => {
    window.addEventListener('resize', resizeObserver)
})

// 撤销恢复
const handleChangeImg = (flag: boolean) => {
    currentImg.value = flag ? currentImg.value + 1 : currentImg.value - 1
    imgBox.src = id.value == 1?imgHistoryList.value[currentImg.value].baseUrl:imgHistoryList.value[currentImg.value].url as string
    imgBox.onload = () => {
        setCanvasImage()
    }
}

// 重置操作
const handleResetDraw = () => {
    currentImg.value = 0
    imgHistoryList.value = [imgHistoryList.value[0]]
    handleResetCropper()
    switch (id.value) {
        case 1:
            rotationBarRef.value?.resetRotation()
            break;
        default:
            break;
    }
    setCanvasImage()
}

// 取消按钮
const handleCancel = () => {

};
// 确认按钮
const handleConfirm = async () => {

}

defineExpose({
    createImgTools
})
</script>

<style scoped lang="scss">
@import '@/components/imgTools/styles/index';
</style>
